package com.example.onlinemonitoring.comCenter;

import com.example.onlinemonitoring.Util.CommPortManager;
import com.example.onlinemonitoring.Util.HexUtil;
import com.example.onlinemonitoring.model.Pdmssensor;
import com.example.onlinemonitoring.model.Pdmshistory;
import com.example.onlinemonitoring.model.Appdevice;
import com.example.onlinemonitoring.serviceImpl.PdmssensorServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.context.annotation.Scope;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/*
高端局放
*/
@Service("pdmsCom")
@Scope("prototype")
public class PdmsCom extends CommPortManager {
    private int nextstep = 0;
    private static final int StartDataGather = 0;// 开始采集
    private static final int PauseDataGather = 1;// 暂停采集
    int DCComponent = 5000;            //采集控制器直流分量
    int DCComponent2 = 5000;            //采集控制器直流分量2
    int TriggerValue = 800;           //采集控制器触发值
    //float DischargeCoef = 0.025f;        //放电量放大系数
    String pattern = "fafa0005";
    float intv = 1;
    float lastphase = 0;
    Lock lck = new ReentrantLock();
        @Autowired
        private PdmssensorServiceImpl pdmssensorServiceImpl;

        @Override
        public void receiveData(String str) {
            if (str.length() < 40) {
                return;
            }

            String strs = str;
            String qba = str.substring(56, str.length() - 56);
            int cnt = qba.length()/8;
            intv=360.0f/(cnt-1);
        
            int posnext = str.indexOf(pattern,4);
            while(posnext>0)
            {
                 String lenstr = str.substring(0, 4);
                //转地址
                Integer lenint = parseHex4(lenstr);
                int len = lenint;
                if(len>0 && len==posnext)//帧合法添加1帧
                {
                    strs = str.substring(4, str.length());
                    ///lck.lock();
                    receiveDatas(strs);
                    //lck.unlock(); 
                }
                else
                {
                    strs = str.substring(posnext, str.length());
                }
                posnext = strs.indexOf(pattern,4);
                lastphase += intv ;
            }

    
        }

        public void receiveDatas(String str) {
            try {
                str = str.toUpperCase();
                setText(str);

                if (str.length()<40)
                return;
  
                reSend[addrindex] = 0;
                //addrindex++;

                float chargevalue;
                int chargecount;
                int start_index = 56;
                if(pattern.equals(str.substring(0, 8))){
                    for(int i=0;i<8;i++)
                    {
                        setText("设备返回数据： 站点号：" + ad.getStationid() + " 设备组：" + ad.getDevicegroup() + " 设备地址：" + ad.getDeviceaddr() + " 监测点：" + i+1);
                        chargecount = parseHex4(str.substring(start_index + i*4, start_index + 4 + i*4));
                        chargevalue = parseHex4(str.substring(start_index + 32 + i, start_index + 33 + i));

                        Pdmssensor pdmssensor =  new Pdmssensor();
                        pdmssensor.setStationid(ad.getStationid());
                        pdmssensor.setDevicegroup(ad.getDevicegroup());
                        pdmssensor.setDeviceaddr(addrindex);
                        pdmssensor.setChannel(i + 1);
                        Pdmssensor record = pdmssensorServiceImpl.getModel(pdmssensor);
                        if (record == null) {
                            setText("当前数据库无监测点：设备地址" + addrindex + "的监测点" + " ！ 请先添加该监测点！");
                            return;
                        }
                        pdmssensor.setlastphase(lastphase);
                        pdmssensor.setLastchargecount(chargecount);
                        pdmssensor.setLastchargemount(chargevalue);
                        AddAndUpdate(record,pdmssensor); 
                    }
                }else{
                    setText("从设备返回的数据有误！请检查串口！");
                }   
               


            } catch (Exception ex) {
                ex.printStackTrace();
                setText("从设备返回的数据有误！请检查串口！");
            }
        }

        @Transactional
        private void AddAndUpdate(Pdmssensor record,Pdmssensor sensor) {
            int alarmLevel = 0;// 报警等级
            String alarmMessage = "";// 报警消息
            if (
                record.getDischargecountalarmvalue() == null ||
                record.getDischargecountalarmrelievevalue() == null ||
                record.getDischargecountwarnvalue() == null ||
                record.getDischargecountwarnrelievevalue() == null||
                record.getDischargeamountalarmvalue() == null ||
                record.getDischargeamountalarmrelievevalue() == null ||
                record.getDischargeamountwarnvalue() == null ||
                record.getDischargeamountwarnrelievevalue() == null 
        ) {
            setText("设备地址" + record.getDeviceaddr() + " 未设置报警值！");
            return;
        }
        List<Integer> array = new ArrayList<>();
        sensor.setlastchargemountalarmstatus(
            GetAlarmStatus(isnull(sensor.getLastchargemount()), isnull(record.getDischargeamountalarmvalue()),
                    isnull(record.getDischargeamountalarmrelievevalue()), isnull(record.getDischargeamountwarnvalue()),
                    isnull(record.getDischargeamountwarnrelievevalue()),
                    isnull(sensor.getlastchargemountalarmstatus()), true, "放电量", record.getDevicegroup(), record.getDeviceaddr(),
                    record.getPointname()));
        alarmMessage += GetAlarmMessage(sensor.getlastchargemountalarmstatus(), "放电量");
        array.add(sensor.getlastchargemountalarmstatus());

        sensor.setlastchargecountalarmstatus(
            GetAlarmStatus(isnull(sensor.getLastchargecount()), isnull(record.getDischargecountalarmvalue()),
                    isnull(record.getDischargecountalarmrelievevalue()), isnull(record.getDischargecountwarnvalue()),
                    isnull(record.getDischargecountwarnrelievevalue()),
                    isnull(sensor.getlastchargecountalarmstatus()), true, "放电次数", record.getDevicegroup(), record.getDeviceaddr(),
                    record.getPointname()));
        alarmMessage += GetAlarmMessage(sensor.getlastchargecountalarmstatus(), "放电次数");
        array.add(sensor.getlastchargecountalarmstatus());

        alarmLevel = HexUtil.MAX(array);
           
            sensor.setLastalarmlevel(alarmLevel);
            sensor.setLastalarmmessage(alarmMessage);
            sensor.setLastcommunicationstatus(0);
            sensor.setLastdatatime(new Date());
            sensor.setLasthisdatatime(addHistory(record));
            if ( pdmssensorServiceImpl.Update(sensor, false) == 0) {
                setText("更新实时数据失败，请检查数据库连接");
            }
        }
        private Date addHistory(Pdmssensor sensor) {
            if (sensor != null) {
                if (sensor.getLasthisdatatime() == null) {
                    add(sensor);
                    return new Date();
                } else {
                    long lasttime = 0;
                    long nowtime = 0;
                    try {
                        lasttime = HexUtil.todate(sensor.getLasthisdatatime()).getTime();
                        nowtime = HexUtil.todate(new Date()).getTime();
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    int timersp = 60000;
                    if (sensor.getLastalarmlevel() != 0) {
                        timersp = ad.getHisalarmtimersp()*1000;
                    } else {
                        timersp = ad.getHistimersp()*1000;
                    }
                    if (lasttime + timersp < nowtime) {
                        add(sensor);
                        return new Date();
                    }
                }
            }
            return null;
        }

        private void add(Pdmssensor sensor) {
            Pdmshistory his = new Pdmshistory();
            his.setDeviceaddr(sensor.getDeviceaddr());
            his.setDevicegroup(sensor.getDevicegroup());
            his.setAlarmlevel(sensor.getLastalarmlevel());
            his.setAlarmmessage(sensor.getLastalarmmessage());
            his.setDatatime(sensor.getLastdatatime());
            his.setPointname(sensor.getPointname());
            his.setStationid(sensor.getStationid());
            his.setChannel(sensor.getChannel());
            his.setphase(sensor.getlastphase());
            his.setChargecount(sensor.getLastchargecount());
            his.setChargeamount(sensor.getLastchargemount());
            pdmssensorServiceImpl.Add(his);
        }


        @Async("threadPool")
        public void startSendThread(Appdevice Appdevice) throws Exception {


             String cstr = "";
             String cmdtype = "";
             String nametype = "";
            int timersp = (int) Math.round(Appdevice.getTimersp() * 1000);
            while (issend.get(Thread.currentThread().getId()) != null) {
                if (isrun) {
                if (addrindex > Appdevice.getAddrmax() || addrindex < Appdevice.getAddrmin())
                    addrindex = Appdevice.getAddrmin();
                    addrindex++;
                switch (nextstep) {
                    case StartDataGather:    
                    //cstr = String.format(Appdevice.getCmd(), String.format("%02X", addrindex));
                    cstr = "fafa000501" + String.format("%02X", 0x000000ff&DCComponent) + String.format("%02X", (0x0000ff00&DCComponent)>>8) + String.format("%02X", 0x000000ff&TriggerValue) + String.format("%02X", (0x0000ff00&TriggerValue)>>8);
                    try {
                        Send(cstr);
                    } catch (Exception EX) {
                        setText(EX.toString());
                    }
                    setText("向" + Appdevice.getName() + "设备发送指令" + cstr);
                    reSend[addrindex]++;
                    if (reSend[addrindex] > 3) {
                    pdmssensorServiceImpl.UpdateStatus(ad, addrindex,1);
                    reSend[addrindex] = 0;
                    nextstep = PauseDataGather;
                    }
                    break;
                                            
                    case PauseDataGather: 
                    //cstr = String.format(Appdevice.getCmd(), String.format("%02X", addrindex));
                    cstr = "fafa000500" ;
                    try {
                        Send(cstr);
                    } catch (Exception EX) {
                        setText(EX.toString());
                    }
                    setText("向" + Appdevice.getName() + "设备发送指令" + cstr);
                    reSend[addrindex]++;
                    if (reSend[addrindex] > 3) {
                    pdmssensorServiceImpl.UpdateStatus(ad, addrindex,1);
                    reSend[addrindex] = 0;
                    nextstep = StartDataGather;                    
                    }

                    break;

                }
                } else if (rescode != 0) {
                    setText(resmsg[rescode]);
                }
                Thread.sleep(timersp);               
            }
        }

        // @Async("threadPool")
        // public void startReceiveThread(){
        //     isrecv.put(Thread.currentThread().getId(), true);
        //     while (isrecv.get(Thread.currentThread().getId()) != null) {
        //         //这里根据实际协议替换,解析方法recvCrc16;recvSum();
        //         recv();
        //         try {
        //             Thread.sleep(interval);
        //         } catch (InterruptedException e) {
        //             e.printStackTrace();
        //         }
        //     }
        // }
}
